using System;
using System.Collections.Generic;
using Firestarter.Test.Base;
using FireStarterModeller.BO;
using Habanero.Base;
using Habanero.BO;
using NUnit.Framework;

namespace FireStarterModeller.Test.BO
{
    /// <summary>
    ///DMClass must have at least one property
    ///Unique constraint must have property
    ///Relationship must have property and related property
    ///Entity must have objectID
    ///Entity must have ObjectID with at least one property.
    ///DMClass must have UIDef
    ///GridDef must have at least one prop
    ///If has filterDef must have at least one prop
    ///All props in DMClasss must be in formdef except primarykeys and foreign keys
    /// </summary>
    [TestFixture]
    public class TestDMClassRules
    {
        [SetUp]
        public void SetupTest()
        {
            //Runs every time that any testmethod is executed
            TestUtilsDomain.SetupTest();
            BORegistry.DataAccessor = new DataAccessorInMemory();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetup()
        {
            //Code that is executed before any test is run in this class. If multiple tests
            // are executed then it will still only be called once.
            TestUtilsDomain.SetupFixture();
        }

        [TearDown]
        public void TearDownTest()
        {
            //runs every time any testmethod is complete
        }

        #region TestDMClassRules

        [Test]
        public void Test_HasWarnings_WhenNoObjectID_ShouldReturnTrue()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            dmClass.Properties.CreateBusinessObject();
            dmClass.UIViews.CreateBusinessObject();
            //---------------Assert Precondition----------------
            string msg;
            Assert.IsTrue(dmClass.Status.IsValid(out msg), "Err Msg : " + msg);
            Assert.IsNull(dmClass.ObjectIdentity);
            Assert.AreEqual(1, dmClass.Properties.Count);
            Assert.AreEqual(1, dmClass.UIViews.Count);
            //---------------Execute Test ----------------------
            IList<IBOError> errors;
            bool hasWarnings = dmClass.Status.HasWarnings(out errors);
            //---------------Test Result -----------------------
            Assert.IsTrue(hasWarnings);
            Assert.AreEqual(1, errors.Count);
            StringAssert.Contains("must have an ObjectID with at least one Property", errors[0].Message);
        }

        [Test]
        public void Test_HasWarnings_WhenObjectIDDoesNotHaveProperties_ShouldReturnTrue()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            dmClass.UIViews.CreateBusinessObject();
            dmClass.ObjectIdentity = new DMObjectIdentity();
            //---------------Assert Precondition----------------
            string msg;
            Assert.IsTrue(dmClass.Status.IsValid(out msg), "Err Msg : " + msg);
            Assert.IsNotNull(dmClass.ObjectIdentity);
            Assert.AreEqual(0, dmClass.Properties.Count);
            Assert.AreEqual(1, dmClass.UIViews.Count);
            //---------------Execute Test ----------------------
            IList<IBOError> errors;
            bool hasWarnings = dmClass.Status.HasWarnings(out errors);
            //---------------Test Result -----------------------
            Assert.IsTrue(hasWarnings);
            Assert.AreEqual(2, errors.Count);
            StringAssert.Contains("must have at least one Property", errors[0].Message);
            StringAssert.Contains("must have an ObjectID with at least one Property", errors[1].Message);
        }


        [Test]
        public void Test_HasWarnings_WhenNoUIView_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            DMProperty property = dmClass.Properties.CreateBusinessObject();
            dmClass.ObjectIdentity = dmClass.CreateObjectIdentity(property);
            //---------------Assert Precondition----------------
            string msg;
            Assert.IsTrue(dmClass.Status.IsValid(out msg), "Err Msg : " + msg);
            Assert.AreEqual(1, dmClass.Properties.Count);
            Assert.IsNotNull(dmClass.ObjectIdentity);
            Assert.AreEqual(1, dmClass.ObjectIdentity.Properties.Count);
            Assert.AreEqual(0, dmClass.UIViews.Count);
            //---------------Execute Test ----------------------
            IList<IBOError> errors;
            bool hasWarnings = dmClass.Status.HasWarnings(out errors);
            //---------------Test Result -----------------------
            Assert.IsFalse(hasWarnings);
            Assert.AreEqual(0, errors.Count);
        }

        [Test]
        public void Test_HasWarnings_WhenAllSetUp_ShouldReturnFalse()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateUnsavedValidDMClass();
            DMProperty property = dmClass.Properties.CreateBusinessObject();
            dmClass.ObjectIdentity = dmClass.CreateObjectIdentity(property);
            dmClass.UIViews.CreateBusinessObject();
            //---------------Assert Precondition----------------
            string msg;
            Assert.IsTrue(dmClass.Status.IsValid(out msg), "Err Msg : " + msg);
            Assert.AreEqual(1, dmClass.Properties.Count);
            Assert.IsNotNull(dmClass.ObjectIdentity);
            Assert.AreEqual(1, dmClass.ObjectIdentity.Properties.Count);
            Assert.AreEqual(1, dmClass.UIViews.Count);
            //---------------Execute Test ----------------------
            IList<IBOError> errors;
            bool hasWarnings = dmClass.Status.HasWarnings(out errors);
            //---------------Test Result -----------------------
            Assert.IsFalse(hasWarnings);
            Assert.AreEqual(0, errors.Count);
        }

        #endregion
    }
}